package org.dromara.system.dict.spi;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Map;

/**
 * spi上下文
 */
@Component
public class SpiContext implements ApplicationContextAware {

    public static final String SPI_PREFIX = "spi_";

    private static ApplicationContext APPLICATIONCONTEXT;

    private static void set(ApplicationContext applicationContext) {
        SpiContext.APPLICATIONCONTEXT = applicationContext;
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        set(applicationContext);
    }

    /**
     * 根据类型获取对象
     *
     * @param clz      clz类型
     * @param <T>具体的对象
     * @return 扩展点对象集合
     */
    public static <T> Collection<T> getSpi(Class<T> clz) {
        Map<String, T> beansOfType = APPLICATIONCONTEXT.getBeansOfType(clz);
        return beansOfType.values();
    }

    /**
     * 根据类型获取对象
     *
     * @param clz      clz类型
     * @param <T>具体的对象
     * @return 扩展点对象集合
     */
    public static <T> T getOneSpi(Class<T> clz) {
        return APPLICATIONCONTEXT.getBean(clz);
    }

    /**
     * 根据类型获取对象
     *
     * @param clz      clz类型
     * @param <T>具体的对象
     * @return 扩展点对象集合
     */
    public static <T> T getSpi(String name, Class<T> clz) {
        Map<String, T> beansOfType = APPLICATIONCONTEXT.getBeansOfType(clz);
        return beansOfType.get(SPI_PREFIX + name);
    }
}
